package com.hugoo.core.db;

import com.hugoo.imp.buzz.ImpInfo;
import com.hugoo.rpt.PageInfo;
import com.hugoo.rpt.busz.HtmlGenAction;
import java.sql.*;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
 * @author Hugoo.Chan
 */
public class DBC {

    private final static Log log = LogFactory.getLog(DBC.class);
    private Connection conn;
    private Statement stmt;
    private ResultSet rs;

    public ImpInfo initDatabase(ImpInfo impInfo) {
        try {
            conn = Conn.conn(null);
            conn.setAutoCommit(false);
            stmt = conn.createStatement();
            if (!impInfo.validateSysDb()) {
                List<String> ls = impInfo.procDataSql();
                log.info("正在处理数据库：" + ls);
                for (String s : ls) {
                    stmt.addBatch(s);
                }
                int[] rl = stmt.executeBatch();//暂时不处理本部分的结果集
                conn.commit();
                Conn.release(stmt, conn);
            }
        } catch (SQLException ex) {
            log.warn("执行数据错库初始化异常！", ex);
        } finally {
            Conn.release(conn);
        }
        return impInfo;
    }

    public boolean impData(ImpInfo impInfo) {
        try {
            conn = Conn.conn(null);
            conn.setAutoCommit(false);
//            sp = conn.setSavepoint();
            //////////////////执行预处理操作///////////
            if (impInfo.hasPreProc()) {
                this.exec_proc(conn, impInfo.preProc());
            }
            //////////////////导入处理操作///////////
            this.exec_sql(conn, impInfo.impProc());
            //////////////////执行扫尾处理操作///////////
            if (impInfo.hasLstProc()) {
                this.exec_proc(conn, impInfo.lstProc());
            }
            conn.commit();
            conn.setAutoCommit(true);
        } catch (SQLException ex) {
            log.warn("执行导入数据错误！", ex);
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException ex1) {
                log.warn("回滚数据库存在异常！", ex1);
            }
            return false;
        } catch (Exception e) {
            log.warn("执行导入数据错误！", e);
            return false;
        } finally {
            Conn.release(conn);
        }
        return true;
    }

    private boolean exec_sql(Connection conn, ImpProc proc) throws SQLException, Exception {
        log.info("准备执行语句：【" + proc.procSql() + "】");
        PreparedStatement psmt = conn.prepareStatement(proc.procSql());
        proc.preProc(psmt);
        conn.commit();
        Conn.release(psmt);
        return true;
    }

    private boolean exec_proc(Connection conn, Call cll) throws SQLException {
        log.info("准备执行语句：【" + cll.procSql() + "】");
        CallableStatement ppc = conn.prepareCall(cll.procSql());
        cll.proc(ppc, log);//执行存储过程
        conn.commit();
        Conn.release(ppc);
        return true;
    }

    public PageInfo loadPageInfo(PageInfo pageInfo) {
        try {
            long t, s = System.currentTimeMillis();
            conn = Conn.conn(pageInfo.getDbl());
            stmt = conn.createStatement();
            if (pageInfo instanceof HtmlGenAction) {
                HtmlGenAction pi = ((HtmlGenAction) pageInfo);
                rs = stmt.executeQuery(pi.getQueryRowsSql());
                rs.next();
                pi.total = rs.getInt(1);
                pi.cacl();//计算分页信息
                Conn.release(stmt, rs);
                log.info("获取数据记录集【" + pi.total + "】，共花费" + (System.currentTimeMillis() - s) + "ms。");
                stmt = conn.createStatement();
            }
            s = System.currentTimeMillis();
            rs = stmt.executeQuery(pageInfo.getQuerySql());
            t = System.currentTimeMillis();
            pageInfo.getResultPack().packResult(rs);
            log.info("执行查询【" + pageInfo.getQuerySql() + "】，共花费" + (t - s) + "/" + (System.currentTimeMillis() - t) + "ms。");
        } catch (Exception ex) {
            log.info("执行查询异常:[" + pageInfo.getQuerySql() + "]", ex);
        } finally {
            Conn.release(conn, stmt, rs);
        }
        return pageInfo;
    }
}
